#!/usr/bin/env  python
#  coding:utf-8

'''
Created on 2015-1-5

@author: scemoon
@summary: 此程序主要目的是生成测试数据，导入json格式测试数据
'''
import random
import db_env
db_env.init()
import json
from django.utils.functional import Promise
from django.utils.encoding import force_text
from django.core.serializers.json import DjangoJSONEncoder
import os

_CHARS = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
_LETTERS = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
_NUMS="0123456789"
_DBTestFile="testdata.json"

class LazyEncoder(DjangoJSONEncoder):
    def default(self, obj):
        if isinstance(obj, Promise):
            return force_text(obj)
        return super(LazyEncoder, self).default(obj)
    
        
class FirtureSerialization(object):
    '''
    @summary: 此类用于生成serialization格式的json方法
    @function format:定义json格式
    
    '''
    @classmethod
    def format(cls,  model,  pk,  **kwargs):
        ''''
        @summary: 定义json格式
        @param model: 设定model名称，如lpts.arch
        @param pk: 设定主键值
        @param kwargs: 设定model其他fields的值，如lpts.arch,指定pk="x86"时，descriptions="x86结构"
        @return: dict, 示例:
                              { "model": "lpts.arch",
                              "pk":  "x86",
                              "fields": {
                                  "descripitions": "x86结构" 
                                              }
                                }
                '''
        return { "model": model,
                "pk":pk,
                "fields":kwargs
                }
   
   
def randwords(length, char_sets=_CHARS):
    '''生成长度为 length 的字符串'''
    x = length / len(char_sets)
    y = length % len(char_sets)
    if x==0:
        words = "".join(random.sample(char_sets, length))
    else:
        words=""
        for i in range(x):
            words = words+"".join(random.sample(char_sets, len(char_sets)))
        words = words+"".join(random.sample(char_sets, y))

    return words

def randtext(length, char_sets=_LETTERS):
    '''生成指定长度的文本
    @param length: word numbers'''
    text=""
    for i in xrange(1, length+1):
        words = randwords(random.randint(5,10), char_sets=char_sets)
        text = text+words+" "
    return text
        
class genDB(object):
    '''产生测试数据，包括Hardware, Produt,  Tester, Job, Environ, Result, Value'''
    _hardware_name = ["联想M4300", "ThinkPadT430", "IBM system x 3650"]
    _product_name = ["中标麒麟高级服务器操作系统", "Red Hat Enterprise Linux", "Ubuntu Desktop"]
    _hardware_scale = 10
    _product_scale = 10
    _tester_scale = 30
    _json_objects = []
    _job_scale = 100
    _result_scale = 500
    _value_scale = 2000
    
    def __init__(self):
        self.init()
        
    def __getattr__(self, key):
        if key == "objects":
            return self._json_objects
        else:
            raise AttributeError
    
    def init(self):
        tester_pks = self.__gen_tester_pk()
        job_pks = [ job_pk for job_pk in self.__gen_Job_pk()]
        #first, 生成Hardware objects
        self._gen_Hardware()
        #生成Product objects
        self._gen_Product()
        #生成Tester objects
        self._gen_Tester(tester_pks)
        #生成Job objects
        self._gen_Job(job_pks, tester_pks)
        #生成Result objects
        self._gen_Result(job_pks)
        #生成Value objects
        self._gen_Value()
        #生成Environ objects
        self._gen_Evrion(job_pks)
    
    def _gen_Hardware(self):
        for  _pk in range(1, self._hardware_scale+1):
            _hardware_object = FirtureSerialization.format("lpts.hardware", _pk,  name=random.choice(self._hardware_name),
                                        cpu=randwords(20),
                                        memory =randwords(10),
                                        disk=randwords(20),
                                        network=randwords(20),
                                        others=randtext(100)
                                         )
            self._json_objects.append(_hardware_object)
            
    
    def  _gen_Product(self):
        for  _pk  in range(1, self._product_scale+1):
            _product_object = FirtureSerialization.format("lpts.product", _pk,  name=random.choice(self._product_name),
                                        release=randwords( 5),
                                        version =randwords( 10),
                                        arch = random.choice(["i686", "x86_64", "mips64el", "mipsel"]),
                                        vendor =randwords( 15),
                                        descriptions = randtext(100)
                                         )
            self._json_objects.append(_product_object)
     
    def __gen_tester_pk(self):
        return [randwords(12)  for i in range(1, self._tester_scale+1)]
    
    def _gen_Tester(self, tester_pks):
        for  _pk in tester_pks :
            _tester_object = FirtureSerialization.format("lpts.tester",  _pk,
                                        position=randwords( 15),
                                        company  =randwords( 25),
                                        mail = random.choice(["x86", "x86_64", "mips64el", "mipsel"])+"@lpts.com",
                                        telephone =randwords(13, char_sets=_NUMS)
                                         )
            self._json_objects.append(_tester_object)
            
    def  __gen_Job_pk(self):
        for i in xrange(1, self._job_scale+1):
            yield randwords(14, char_sets=_NUMS)
    
    def _gen_Job(self, job_pks, tester_pks):
        for _pk in job_pks:
            _job_object = FirtureSerialization.format("lpts.job",  _pk, name=randwords( 16),
                                        hardware= random.randint(1, self._hardware_scale),
                                        os  =random.randint(1, self._product_scale),
                                        scenegroup  = random.choice(["SG001", "SG002", "SG003", "SG004"]),
                                        tester =random.choice(tester_pks),
                                        time ="2013-01-16T08:16:59.844Z"
                                         )
            self._json_objects.append(_job_object)
            
    def _gen_Result(self, job_pks):
        for _pk in xrange(1, self._result_scale+1):
            _result_object = FirtureSerialization.format("lpts.result",  _pk,  index=random.choice(["copy", "add"]),
                                        job= random.choice( job_pks),
                                        scene  =random.choice(["mem0001", "mem0002", "mem0003"]),
                                        parallel =  _pk
                                         )
            self._json_objects.append(_result_object)
            
    def _gen_Value(self):
        for _pk in xrange(1, self._value_scale+1):
            _value_object = FirtureSerialization.format("lpts.value",  _pk,  result=random.choice([_re_pk for _re_pk in xrange(1, self._result_scale+1)]),
                                        iter = _pk,
                                        value  =random.uniform(100,120)
                                        
                                         )
            self._json_objects.append(_value_object)
            
    def _gen_Evrion(self, job_pks):
        for _pk in job_pks:
            _environ_object = FirtureSerialization.format("lpts.environ",  _pk, kernel=randwords( 25),
                                                      kernelcmd=randwords( 25),
                                                      runlevel=random.choice([1,2,3,4,5,6]),
                                                      filesystem=randwords( 25),
                                                      swapsize=randwords( 25),
                                                      packages=random.randint(600,1000),
                                                      gcc=randwords( 25),
                                                      glibc=randwords( 25),
                                                      java=randwords( 25),
                                                      selinux=randwords( 25),
                                                      iptables=randwords( 25),
                                                      services=randtext(100),
                                                      others=randtext(100)
                                                      )
            self._json_objects.append(_environ_object)                                              
   


def get_json_objects():
    dbobjects = genDB().objects
    json_obj = json.dumps(dbobjects,  sort_keys=True, cls=LazyEncoder)
    open(_DBTestFile, "w").writelines(json_obj)
   

if __name__ == "__main__":
    from django.core.management import call_command
    get_json_objects()
    if os.path.isfile(_DBTestFile):
        call_command("loaddata",  _DBTestFile)
    else:
        print "Not Found data file."